package com.nxzh.de.executor.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.nxzh.de.executor.common.constant.CacheConstants;
import com.nxzh.de.executor.common.core.redis.RedisCache;
import com.nxzh.de.executor.common.utils.NumberGroupingUtils;
import com.nxzh.de.executor.common.utils.http.SendHttpRequestUtil;
import com.nxzh.de.executor.domain.Mode;
import com.nxzh.de.executor.service.IReadInstructions;
import com.xxl.job.core.context.XxlJobHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author : haodong.tian
 * @version : v1.0
 * @className : ReadInstructionsImpl
 * @description : 读取集控接口数据
 * @createTime : 2023/6/27 11:50
 */
@Service("ReadInstructionsImpl")
public class ReadInstructionsImpl implements IReadInstructions {
    private static Logger logger = LoggerFactory.getLogger(ReadInstructionsImpl.class);

    @Value("${model.redisUrl}")
    private String redisUrl;

    @Autowired
    private RedisCache cache;

    @Override
    public List<HashMap<String, String>> selectIntefaceDatas(String deviceIds, List<Mode> modes) {

        List<HashMap<String, String>> deviceMap = new ArrayList<>();
        HashMap<Integer, List<HashMap<String, String>>> deviceGroup = new HashMap<>();
        LinkedHashMap<String, Map<String, String>> previousObject = cache.getCacheObject(CacheConstants.DE_SUCK_BACK_KEY);

        JSONObject jsonObject2 = findSuckBackFromDE(deviceIds);
        if (null != jsonObject2) {
            if (null == previousObject) {
                return deviceMap;
            }
            Iterator<String> keys = jsonObject2.keySet().iterator();
            while (keys.hasNext()) {
                HashMap<String, String> dataMap = new HashMap<>();

                String deviceId = keys.next();
                JSONObject jsonObject3 = JSONObject.parseObject(jsonObject2.getString(deviceId));
                String mode = jsonObject3.getString("101");
                String alarmLixie = jsonObject3.getString("11101").toLowerCase();
                if (mode == "0" && ("true".equals(alarmLixie) || "1".equals(alarmLixie))) {
                    logger.info("离线炉台:{}", deviceId);
                    deviceMap.remove(deviceId);
                }

                //上一次炉压数据
                Map<String, String> previousObjectData = previousObject.get(deviceId);

                List<Mode> collect = modes.parallelStream()
                        .filter(workId -> workId.getId().equals(mode))
                        .collect(Collectors.toList());
                if (collect.size() > 0) {
                    // 查询符合条件的数据
                    // 前后压差》10且球阀状态为true
                    if (Double.parseDouble(jsonObject3.getString("3271")) - Double.parseDouble(previousObjectData.get("3271")) > 10 &&
                            "True".equals(jsonObject3.getString("425")) && "False".equals(jsonObject3.getString("545"))) {
//                        if (Math.abs(Double.parseDouble(jsonObject3.getString("1279")) - Double.parseDouble(jsonObject3.getString("1245"))) > Double.parseDouble(collect.get(0).getTorr())) {
                        String lotNo = jsonObject3.getString("1196");
                        dataMap.put("mode", mode + "");
                        dataMap.put("mode_name", collect.get(0).getModeName().replace(" ", ""));
                        dataMap.put("lot_no", lotNo);
//                        dataMap.put("dbzt", jsonObject3.getString("317"));
//                        dataMap.put("sdyl", jsonObject3.getString("1279"));
                        dataMap.put("zsyl", jsonObject3.getString("3271"));
                        dataMap.put("offset", collect.get(0).getTorr());
                        double abs = Math.abs(Double.parseDouble(jsonObject3.getString("3271")) - Double.parseDouble(previousObjectData.get("3271")));
                        dataMap.put("sub", String.format("%.2f", abs));
                        // 工步运行时间
                        dataMap.put("run_time", jsonObject3.getInteger("1043") + ":" + jsonObject3.getInteger("1042") + ":" + jsonObject3.getInteger("1041"));
                        // 批次运行时间
                        dataMap.put("lot_no_time", jsonObject3.getInteger("1038") + ":" + jsonObject3.getInteger("1037") + ":" + jsonObject3.getInteger("1036"));
                        dataMap.put("lot_group", String.valueOf(NumberGroupingUtils.getGroup(Integer.parseInt(deviceId))));
                        dataMap.put("device_id", deviceId);
                        dataMap.put("fbqf_status", jsonObject3.getString("425"));
                        dataMap.put("kcf_status", jsonObject3.getString("545"));
                        dataMap.put("previous_data", String.format("{%s:%s}", deviceId, JSONObject.toJSONString(previousObjectData)));
//                      logger.info("符合的炉台:{}:{}", deviceId,dataMap);
                        if (!deviceGroup.containsKey(NumberGroupingUtils.getGroup(Integer.parseInt(deviceId)))) {
                            List<HashMap<String, String>> list = new ArrayList<>();
                            list.add(dataMap);
                            deviceGroup.put(NumberGroupingUtils.getGroup(Integer.parseInt(deviceId)), list);
                        } else {
                            // 当map中存在该key时，将值追加到该key对应的列表中
                            deviceGroup.get(NumberGroupingUtils.getGroup(Integer.parseInt(deviceId))).add(dataMap);
                        }
                    }
                }
            }
        } else {
            logger.error("获取数据结果为空");
            return deviceMap;
        }

        // 小组内球阀状态为True的压差大于10的数据，超过两条时，才会被记录
        for (Map.Entry<Integer, List<HashMap<String, String>>> entry : deviceGroup.entrySet()) {
            if (entry.getValue().size() < 2) {
                continue;
            }
            int qfcount = 0;
            for (HashMap<String, String> getGroup : entry.getValue()) {
                qfcount += "True".equals(getGroup.get("fbqf_status")) ? 1 : 0;
                if (qfcount > 1) {
                    deviceMap.addAll(entry.getValue());
                    break;
                }
            }
        }
        logger.info("符合公布炉台数据汇总：{}", deviceMap);
        return deviceMap;
    }

    /*
     * 请求DE数据
     */
    public JSONObject findSuckBackFromDE(String devices) {
        JSONObject obj = null;

        JSONObject jsonObject = new JSONObject();
        LinkedList<Integer> dataArray = new LinkedList<>();

        dataArray.add(101);     // 工步
        dataArray.add(1196);    // 批次号
//        dataArray.add(317);     // 大泵状态
        dataArray.add(425);     // 副泵球阀状态
//        dataArray.add(1245);    // 主室压力
//        dataArray.add(1279);    // 压力设定值
        dataArray.add(3271);    // 副室压力
        dataArray.add(545);    // 快冲阀开启状态

        dataArray.add(11101);   // 离线
        dataArray.add(1041);    // 当前工艺运行时间(s)
        dataArray.add(1042);    // 当前工艺运行时间(m)
        dataArray.add(1043);    // 当前工艺运行时间(h)

        dataArray.add(1038);    // 批次运行时间(h)
        dataArray.add(1037);    // 批次运行时间(m)
        dataArray.add(1036);    // 批次运行时间(s)

        jsonObject.put("deviceid", JSONObject.toJSONString(devices.split(",")));
        jsonObject.put("data", dataArray);
        jsonObject.put("command", "readdatas");
        logger.info("请求DE参数:{}", jsonObject);
        String requestResult = SendHttpRequestUtil.doPost(redisUrl, jsonObject);
        if (requestResult != null && requestResult.length() > 0) {
            JSONObject jsonObject1 = JSONObject.parseObject(requestResult);

            String code = jsonObject1.getString("code");
            if ("100".equals(code)) {
                String result = jsonObject1.getString("result");
                obj = JSONObject.parseObject(result);
                cache.setCacheObject(CacheConstants.DE_SUCK_BACK_KEY, obj, 7, TimeUnit.SECONDS);
//                cache.setCacheObject(CacheConstants.DE_SUCK_BACK_KEY_TIME, LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.NORM_DATETIME_PATTERN));
            } else {
                logger.error("获取数据结果为空");
                XxlJobHelper.log("连接接口数据失败:{}", requestResult);
//                cache.deleteObject(CacheConstants.DE_SUCK_BACK_KEY);
            }
        } else {
            XxlJobHelper.log("连接接口数据失败:{}", requestResult);
            logger.error("连接接口数据失败");
//            cache.deleteObject(CacheConstants.DE_SUCK_BACK_KEY);
        }
        return obj;
    }
}

